Electron 应用构建内建浏览器
如何为一个 Electron 应用,新增内建浏览器(built-in browser) 特性?
<webview> 的限制
<webview>内不支持嵌套<webview>(Embedding tags within eachother · Issue #1130 · electron/electron)
架构方案对比
| 方案 | 说明 | 何时选 |
|---|---|---|
外壳 BrowserWindow + 一层 <webview> 标签 |
Codex / Orca 的做法,单层 guest,官方支持 | 想要多标签浏览器且外壳可改写 |
外壳 BrowserWindow + 多个 WebContentsView |
主进程管坐标,不走 <webview> |
需要主进程强控、想脱离 <webview> 长期风险 |
外层 <webview> + 主进程 WebContentsView 铺在其上 |
视觉上像"嵌进外层",实为同层叠加 | 外层 <webview> 是无法拆的黑盒时 |
| 每个"内层"用独立 BrowserWindow / 子窗口 | 完全不依赖 <webview> 嵌套 |
内层数量有限、允许分窗 |
<iframe> + CSP 放开 |
目标站点你可控,允许被 iframe 嵌 | 内嵌自家 Web 应用 |
社区实践
来自 r/electronjs - Reddit 的一手经验:
I am building one right now. When I started out Electron was going to be my last choice because of all the negativity around it. But after exploring pretty much every other option (Native swift, flutter, rust, react native, KMM), I decided electron made the most sense for my use case and my team (just me, that already knows web tech and fears rust).
I first started down the rabbit hole using
<webview>even tho electron recommends not to use it and it's deprecated (webview-tag 文档) but it made the most sense for me because I could just embed it in my react renderer. Eventually tho, for a few reasons, I decided to explore using WebContentsView. This made the architecture much harder as I had to control the layout in the main process, as it wasn't just something I could embed in a react with a div element, but what I came up with is working pretty good.
参考资料
- Stack 浏览器的技术实现 — 另一个团队做 Electron 浏览器的踩坑记录
- samuelmaddock/electron-browser-shell — 开源参考实现
- Electron webview 标签文档
- Electron WebContentsView 文档